#include <iostream>
#include <cmath>

using namespace std;

#define FOUR

#if defined ONE

/**
 * a表示形式参数(parameter)
 * 其实就是函数内部的局部变量
 */
void Print(int a)
{
    cout << "整数:" << a << endl;
}

void Print(double a)
{
    cout << "浮点:" << a << endl;
}

void Print(int a, int b)
{
    cout << "两个整数:" << a << "," << b << endl;
}

int main()
{
    /**
     * 下面的 5 3.14 10，20  表示实参(argument)
     */
    Print(5);
    Print(3.14);
    Print(10, 20);
    return 0;
}

#elif defined TWO

void Swap(int&, int&);   // 函数的声明,只是说明了函数的返回值，函数的名称，函数的参数类型(参数的名称不是很重要)
int  main()
{
    int a = 100;
    int b = 200;

    cout << "交换前,a的值:" << a << endl;
    cout << "交换前,b的值:" << b << endl;
    Swap(a, b);
    cout << "交换后,a的值:" << a << endl;
    cout << "交换后,b的值:" << b << endl;
    return 0;
}

void Swap(int& x, int& y)
{
    int Temp;

    Temp = x;
    x    = y;
    y    = Temp;

    return;
}

/**
 * 传递引用,在函数参数列表中使用引用类型，这样函数内部的修改会影响到实际传递的变量
 * 避免拷贝开销,提高了效率
 *
 * 注意引用的实现,实质上是编译器别名,相比于指针，是名副其实的零开销
 */

#elif defined THREE

/**
 * 这里的 b 有默认值,如果实际参数的值留空,则使用这个默认值20
 */
int sum(int a, int b = 20)
{
    int result;

    result = a + b;

    return (result);
}

int main()
{
    int a = 100;
    int b = 200;
    int result;

    result = sum(a, b);
    cout << "Total Value Is:" << result << endl;

    result = sum(a);
    cout << "Total Value Is:" << result << endl;

    return 0;
}

#elif defined FOUR

/**
 * Lambda函数表达式   C++11提供了对匿名函数的支持，称为Lambda函数(也叫Lambda表达式)
 * Lambda表达式(也叫Lambda函数)把函数看做对象。Lambda表达式可以像对象一样使用，比如可以将它们
 * 赋给变量 和 作为参数传递，还可以像函数一样对其求值
 * 
 * Lambda表达式本质上与函数声明非常类似。Lambda表达式具体形式如下:
 *      [capture](parameters)->return-type{body}
 * 
 * 例如:
 *      [](int x,int y){return x < y;}
 * 
 * 如果没有返回值可以表示为:
 *      [capture](parameters){body}
 * 例如:
 *      []{++global_x;}
 * 
 * 就是说如果Lambda函数没有传回值(例如void),其返回类型可被完全忽略
 * 
 * 在一个更为复杂的例子中，返回类型可以被明确的指定如下(就是明确指定了返回值类型):
 *      [](int x,int y)->int{int z=x+y;return z+x;}
 *      
 * C++变量传递有传值和传引用的区别，可以通过前面的[]来指定
 * 
 * []       沒有定义任何变量。使用未定义变量会引发错误
 * [x,&y]   x以传值方式传入（默认），y以引用方式传入  
 * [&]      任何被使用到的外部变量都隐式地以引用方式加以引用（引用就是变量别名）
 * [=]      任何被使用到的外部变量都隐式地以传值方式加以引用
 * [&,x]    x显式地以传值方式加以引用。其余变量以引用方式加以引用
 * [=,&z]   z显式地以引用方式加以引用。其余变量以传值方式加以引用
 * 
 *  this指针是啥
 */

int main(void)
{
    return 0;
}


#endif

/**
 * 函数声明告诉编译器函数的名称,返回类型和参数的类型 (也就是参数的名称并不重要)。函数定义提供了函数的实际主体
 *
 * 函数名和参数列表一起构成了函数签名(言下之意，就是在函数名称相同的情况下，参数名称不同那么就可以实现重载)
 *
 *
 *
 * C++中，函数重载(Function Overloading)是指在同一作用域内，可以定义多个同名函数，但是这些
 * 函数的参数列表(参数类型,数量或者顺序)必须不同。重载允许函数根据不同的输入参数执行不同的操作
 *
 * C++函数重载的特点:
 *  1.同名函数:函数名相同
 *  2.参数列表不同: 至少满足一下之一: 参数类型不同   参数数量不同  参数顺序不同(当类型不同时)
 *  3.返回类型不影响重载: 仅返回类型不同不能构成重载
 *
 *  默认参数可能引起重载歧义
 *  重载解析在编译时完成(重点)
 * 
 * 
 *  C++ 多态 和  重载  是啥
 */
